/* Copyright (c) 2010 OFXKit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#import "OFXRequestHelperBase.h"


@implementation OFXRequestHelperBase

@synthesize ofxResponse;
@synthesize receivedData;

enum {
  OFXConnectionError = 1
};

- (id) delegate
{
  return delegate;
}

- (void) setDelegate:(id)aDelegate
{
  delegate = aDelegate;
  // if the repsonse is already not nil go ahead and call the delegate method
  // method ofxResponseReceived:(OFXDocumentResponse*)response;
  if ([self ofxResponse] != nil &&
      [aDelegate respondsToSelector:@selector(ofxResponseReceived:)]) 
  {
    [aDelegate ofxResponseReceived:ofxResponse];
  }
}

- (void) sendRequest:(OFXDocumentRequest*)ofxRequest withURL:(NSURL*)url
               error:(NSError**)error
{
  // Create the request.
  NSMutableURLRequest* theRequest = 
    [NSMutableURLRequest requestWithURL:url
                            cachePolicy:NSURLRequestUseProtocolCachePolicy
                        timeoutInterval:60.0];  
  
  NSData*   postData = [[ofxRequest asString] 
                        dataUsingEncoding:NSUTF8StringEncoding];
  [theRequest setHTTPMethod:@"POST"];
  [theRequest setHTTPBody:postData];
  
  [theRequest setValue:@"application/x-ofx" forHTTPHeaderField:@"Content-type"];
  [theRequest setValue:@"*/*, application/x-ofx" forHTTPHeaderField:@"Accept"];
  
  // create the connection with the request
  // and start loading the data
  NSURLConnection* theConnection=[[NSURLConnection alloc] 
                                  initWithRequest:theRequest delegate:self];
  if (theConnection) {
    // Create the NSMutableData to hold the received data.
    // receivedData is an instance variable declared elsewhere.
    receivedData = [NSMutableData data];
  } else {
    // failed to create a connection throw an error
    NSDictionary* userInfo = 
      [NSDictionary dictionaryWithObject:@"Resulting NSURLConnection was nil"
                                  forKey:NSLocalizedDescriptionKey];
    *error = [NSError errorWithDomain:@"OFXError" 
                                code:OFXConnectionError
                            userInfo:userInfo];
    NSLog(@"There was an error");
  }
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
  NSString* response = [[NSString alloc] initWithData:receivedData 
                                             encoding:NSUTF8StringEncoding];
  
  NSError* error;
  ofxResponse = [OFXDocumentResponse ofxDocumentWithContentsOfString:response
                                                            encoding:NSUTF8StringEncoding
                                                               error:&error];
  if ([self delegate] != nil &&
      [[self delegate] respondsToSelector:@selector(ofxResponseReceived:)])
  {
    [[self delegate] ofxResponseReceived:ofxResponse];
  }
}

- (void)connection:(NSURLConnection *)connection 
didReceiveResponse:(NSURLResponse *)response
{
  // This method is called when the server has determined that it
  // has enough information to create the NSURLResponse.
  
  // It can be called multiple times, for example in the case of a
  // redirect, so each time we reset the data.
  [receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
  // Append the new data to receivedData.
  [receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error
{
  // release the connection, and the data object
  NSLog(@"Connection failed with error!");
  
  if ([self delegate] != nil &&
      [[self delegate] respondsToSelector:@selector(ofxRequestDidFailWithError:)])
  {
    [[self delegate] ofxRequestDidFailWithError:error];
  }
}

@end
